#pragma once
#include "md5_tokens.h"
#include "md5_lexer.h"
#include "vector3.h"
#include "quaternion.h"

namespace krryn{
namespace data{
	class md5_parse_error : public std::runtime_error{
	public:
		md5_parse_error(const std::string &a_Error) : runtime_error(a_Error) {}
		virtual ~md5_parse_error() throw() {}
	};

	class md5_syntax_error : public md5_parse_error{
	public:
		md5_syntax_error(const std::string &a_Error) : md5_parse_error(a_Error) {}
		virtual ~md5_syntax_error() throw() {}
	};

	class md5_parser{
	public:
		md5_parser(const std::string &a_Filename, size_t a_MemoryBudgetBytes);
		virtual ~md5_parser() {}

		virtual void parse() = 0;
	protected:
		size_t m_MemoryBudget;
		size_t m_BytesLeft;

		void header();
		math::vector3f vector();
		math::quaternionf quat();

		void match(md5_tags a_Tag);
		void match_number();
		void move();
		void error(const std::string &a_Error);
		void unexpected(md5_tags a_Expected, md5_tags a_Current = none);
		void request_allocation(size_t a_Size);

		md5_token m_Look;
		md5_lexer m_Lexer;
	};
}
}